package eduware.dozent;

import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Random;

import eduware.Program;
import eduware.ctrl.Ctrl;
/**
 * An Enum containing the tutor's mood state.<br>
 * With this Enum it is easy to introduce a new mood index.
 * 
 * @author Florian Bausch
 * 
 */
public enum MoodState {
	HUNGER(100.0f, Ctrl.getInstance().getDozentProfile().getHungerRate(), 100.0f, "Hunger"), THIRST(100.0f, Ctrl.getInstance().getDozentProfile().getThirstRate(), 100.0f,
			"Thirst"), TOILET(100.0f, Ctrl.getInstance().getDozentProfile().getToiletRate(), 100.0f, "Toilet"), SLEEP(100.0f,
					Ctrl.getInstance().getDozentProfile().getSleepRate(), 100.0f, "Sleep"), MOOD(100.0f, Ctrl.getInstance().getDozentProfile().getMoodRate(), 100.0f, "Mood");

	private float index, formerIndex, rate;
	private String name;

	private static int sleep;
	
	static Random rnd = new Random( System.currentTimeMillis() );

	/**
	 * Decreases all mood indices by the value defined in <code>rate</code>, if
	 * the value of <code>pause</code> is 0. If <code>pause</code> is greater
	 * than 0, <code>pause</code> is decreased by 1.
	 */
	public synchronized static void decreaseMood() {
		
		GregorianCalendar gc = new GregorianCalendar();
		float timeRatio = 1;
		try {
			timeRatio = Program.getInstance().getProf().getProfile().getTdb().getTimeRatio(gc.get(Calendar.HOUR_OF_DAY), gc.get(Calendar.MINUTE));
			System.out.println("Current mood ratio: " + timeRatio);
		} catch (Exception e) {
			e.printStackTrace();
		}
		for (MoodState m : MoodState.values()) {
			// add 25 percent difference
			float rate = m.getRate();
			float changeRate = rate - (rate*0.25f - (rate*0.5f*rnd.nextFloat()));
			
			// add time dependency
			changeRate = changeRate*timeRatio;
			m.setIndex(m.getIndex() - changeRate);
		}
	}

	/**
	 * Creates the data for a mood index
	 * 
	 * @param index
	 *            The value of the index
	 * @param rate
	 *            The value of the decreasing rate
	 * @param formerIndex
	 *            The value of the formerIndex
	 */
	private MoodState(float index, float rate, float formerIndex, String name) {
		this.index = index;
		this.rate = rate;
		this.formerIndex = formerIndex;
		this.name = name;
	}

	/**
	 * Getter for the index
	 * 
	 * @return the index
	 */
	public synchronized float getIndex() {
		return index;
	}

	/**
	 * Sets a new index and sets the formerIndex to the old index
	 * 
	 * @param i
	 *            the new index
	 */
	public synchronized void setIndex(float i) {
		i = i < 0.0f ? 0.0f : (i > 100.0f ? 100.0f : i);
		float formerIndex = this.index;
		this.index = i;
		this.formerIndex = formerIndex;
	}

	/**
	 * Getter for the formerIndex
	 * 
	 * @return the formerIndex
	 */
	public synchronized float getFormerIndex() {
		return formerIndex;
	}

	/**
	 * Getter for the rate
	 * 
	 * @return the rate
	 */
	public synchronized float getRate() {
		return rate;
	}

	/**
	 * Sets a new decreasing rate
	 * 
	 * @param rate
	 *            the rate
	 */
	public synchronized void setRate(float rate) {
		this.rate = rate;
	}

	/**
	 * Increase the index by the given delta. If delta is negative, it decreases
	 * the index.
	 * 
	 * @param delta
	 *            The delta value.
	 */
	public synchronized void increaseIndex(float delta) {
		this.setIndex(this.index + delta);
	}

	/**
	 * Prints the index and the formerIndex of the MoodState<br>
	 * <b>Only for debugging purposes.</b>
	 * 
	 * @param m
	 *            The MoodState that shall be printed.
	 */
	public static void printIndex(MoodState m) {
		System.out
				.println(m.name + ": " + m.index + "fIndex: " + m.formerIndex);
	}

	/**
	 * Prints the index and the formerIndex of all MoodStates<br>
	 * <b>Only for debugging purposes.</b>
	 */
	public static void printIndices() {
		for (MoodState m : MoodState.values()) {
			System.out.println(m.name + ": " + m.index + "fIndex: "
					+ m.formerIndex);
		}
	}

	/**
	 * Returns, if the tutor is sleeping
	 * 
	 * @return true, if sleeping
	 */
	public static boolean isSleeping() {
		return (sleep > 0) ? true : false;
	}

	/**
	 * Sets how many intervals the tutor will sleep.
	 * 
	 * @param The
	 *            intervals.
	 */
	public static void setSleep(int intervals) {
		sleep = (intervals >= 0) ? intervals : 0;
		Ctrl.getInstance().interrupt();
	}

	/**
	 * Returns how many intervals the tutor will sleep
	 * 
	 * @return The intervals.
	 */
	public static int getSleep() {
		return sleep;
	}

	/**
	 * Returns the average value of the moods.
	 * 
	 * @return The average mood.
	 */
	public static int getMood() {
		int i = 0;
		float mood = 0.0f;
		for (MoodState m : MoodState.values()) {
			mood += m.getIndex();
			i++;
		}
		return (int) (mood / i);
	}

}
